﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Collections.ObjectModel;
using System.Data;
using System.Windows.Media.Imaging;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Controls;
using System.Globalization;
using produccion.modelo;
using produccion.AccesoDatos;
using produccion.clases;
using System.Windows.Input;
using System.Collections.Specialized;

namespace produccion.vistamodelo
{
    class VMMantenimientodePiezas : ViewModelBase
    {
        #region Campos

            private List<CLSTABPIE> _lispieza = new List<CLSTABPIE>();
            private ProcesoProduccionRepositorio _repositorio = new ProcesoProduccionRepositorio();

        #endregion

        #region constructor

            public VMMantenimientodePiezas()
            {
                try
                {
                    consultaPiezas();
                    lispiezas.CollectionChanged += OnCollectionChanged;

                    if (MDOgeneral.conexion == null || MDOgeneral.conexion.State == ConnectionState.Closed)
                    {
                        MDOgeneral.conectar();
                    }
                    strTituloVentana = "Mantenimiento de piezas - Usuario: " + MDOgeneral.usuario + " - [FRMMantenimientodePiezas]";
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

        #endregion

        #region Interfaces publicas

            private string _strTituloVentana;
            public string strTituloVentana
            {
                get { return _strTituloVentana; }
                set { _strTituloVentana = value; base.OnPropertyChanged("strTituloVentana"); }
            }

            public List<CLSTABPIE> lispieza
            {
                get { return _lispieza; }
                set { _lispieza = value; base.OnPropertyChanged("lispieza"); }
            }

            private MDOgeneral.mensaje _msn = new MDOgeneral.mensaje();
            public MDOgeneral.mensaje msn
            {
                get { return _msn; }
                set { _msn = value; base.OnPropertyChanged("msn"); }
            }

            private ObservableCollection<VMPiezas> _lispiezas = new ObservableCollection<VMPiezas>();
            public ObservableCollection<VMPiezas> lispiezas
            {
                get { return _lispiezas; }
                set { _lispiezas = value; base.OnPropertyChanged("lispiezas"); }
            }

            private VMPiezas _selpieza;
            public VMPiezas selpieza
            {
                get { return _selpieza; }
                set
                {
                    _selpieza = value;
                    base.OnPropertyChanged("selpieza");
                }
            }

            private Boolean _logValido = true;
            public Boolean logValido
            {
                get { return _logValido; }
                set
                {
                    _logValido = value;
                    base.OnPropertyChanged("logValido");
                }
            }

        #endregion

        #region Comandos
            RelayCommand _cmdSalir;
            public ICommand cmdSalir
            {
                get
                {
                    if (_cmdSalir == null)
                    {
                        _cmdSalir = new RelayCommand(Salir);
                    }
                    return _cmdSalir;
                }
            }

            RelayCommand _cmdEliminar;
            public ICommand cmdEliminar
            { 
                get
                {
                    if (_cmdEliminar == null)
                    {
                        _cmdEliminar = new RelayCommand(r => eliminarPieza());
                    }
                    return _cmdEliminar;
                }
            }

            RelayCommand _cmdGrabar;
            public ICommand cmdGrabar
            {
                get
                {
                    if (_cmdGrabar == null)
                    {
                        _cmdGrabar = new RelayCommand(r => grabarPieza());
                    }
                    return _cmdGrabar;
                }
            }

        #endregion

        #region Metodos

            public void consultaPiezas()
            {
                try
                {
                    lispieza = _repositorio.consultarPiezas();
                    List<VMPiezas> all = (from cust in lispieza select new VMPiezas(cust)).ToList();
                    foreach (VMPiezas pie in all)
                    {
                        pie.validarPieza += validaPieza;
                        pie.PropertyChanged += OnPropertyChanged;
                    }
                    lispiezas = new ObservableCollection<VMPiezas>(all);
                    lispiezas.CollectionChanged += OnCollectionChanged;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
            { 
                logValido=((from pie in lispiezas where pie.IsValid.Equals(false) select pie.IsValid).ToList().Count()) > 0 ? true : false;
            }

            void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                try
                {
                    if (e.NewItems != null && e.NewItems.Count > 0)
                    {
                        foreach (VMPiezas pie in e.NewItems)
                        {
                            pie.validarPieza += validaPieza;
                            pie.PropertyChanged += OnPropertyChanged;
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public string validaPieza(string strCodigoPie)
            {
                try
                {
                    int i = (from pie in lispiezas where pie.codpie_pie.Trim().Equals(strCodigoPie.Trim()) select pie).ToList().Count();
                    if (i > 1)
                    {
                        return "Código de pieza ya existe";
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            private void grabarPieza()
            {
                try
                {
                    List<CLSTABPIE> lstAgregar = (from pie in lispiezas where pie.agregar.Equals(true) select pie.getPiezas()).ToList();
                    List<CLSTABPIE> lstActualizar = (from pie in lispiezas where pie.actualizar.Equals(true) select pie.getPiezas()).ToList();
                    List<CLSTABPIE> lstEliminar = (from pie in lispiezas where pie.eliminar.Equals(true) select pie.getPiezas()).ToList();

                    if (_repositorio.guardarPiezas(lstActualizar, lstEliminar, lstAgregar))
                    {
                        msn.texto = "La información de Piezas fue gauardada exitosamente.";
                        msn.tipo = true;
                        consultaPiezas();
                    }
                    else
                    {
                        msn.texto = "La información de piezas no se pudo grabar.";
                        msn.tipo = false;
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            private void eliminarPieza()
            {
                try
                {
                    if (selpieza.agregar)
                        lispiezas.Remove(selpieza);
                    else
                        selpieza.eliminar = !selpieza.eliminar;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public void Salir(Object frmformulario)
            {
                ((Window)frmformulario).Close();
            }

        #endregion

 
        #region Vistas Modelo
        public class VMPiezas : ViewModelBase, IDataErrorInfo
        {
            #region campos
                private CLSTABPIE _piezas = new CLSTABPIE();
                public delegate string validarCodigoPieza(string codpie_pie);
            #endregion

            #region constructor

                public VMPiezas(CLSTABPIE piezas)
                {
                    _piezas = piezas;
                }

                public VMPiezas()
                {
                    agregar = true;
                    base.OnPropertyChanged("codpie_pie");
                }

            #endregion

            #region metodos

                public CLSTABPIE getPiezas()
                {
                    return _piezas;
                }

            #endregion

            #region interfaces publicas

                public validarCodigoPieza validarPieza;

                public string codpie_pie
                {
                    get { return _piezas.CODPIE_PIE; }
                    set 
                    {
                        if (agregar == true)
                        {
                            _piezas.CODPIE_PIE = value;
                            base.OnPropertyChanged("codpie_pie");
                        }
                    }
                }

                public string nombre_pie
                {
                    get { return _piezas.NOMBRE_PIE; }
                    set 
                    {
                        if (_piezas.NOMBRE_PIE != value && agregar == false)
                            actualizar = true;
                        _piezas.NOMBRE_PIE = value;                        
                        base.OnPropertyChanged("nombre_pie");
                    }
                }

                private bool _actualizar = false;
                public bool actualizar
                {
                    get { return _actualizar; }
                    set { _actualizar = value; base.OnPropertyChanged("actualizar"); }
                }

                private bool _eliminar = false;
                public bool eliminar
                {
                    get { return _eliminar; }
                    set { _eliminar = value; base.OnPropertyChanged("eliminar"); }
                }

                private bool _agregar = false;
                public bool agregar
                {
                    get { return _agregar; }
                    set { _agregar = value; base.OnPropertyChanged("agregar"); }
                }

            #endregion

            #region IDataErrorInfo Members

                string IDataErrorInfo.Error { get { return null; } }

                string IDataErrorInfo.this[string propertyName]
                {
                    get { return this.GetValidationError(propertyName); }
                }

            #endregion

            #region Validation

                /// <summary>
                /// Returns true if this object has no validation errors.
                /// </summary>
                /// 

                public bool IsValid
                {
                    get
                    {
                        foreach (string property in ValidatedProperties)
                            if (GetValidationError(property) != null)
                                return false;
                        return true;
                    }
                }

                static readonly string[] ValidatedProperties = 
                { 
                    "codpie_pie",
                    "nombre_pie"
                };

                string GetValidationError(string propertyName)
                {
                    if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                        return null;

                    string error = null;

                    switch (propertyName)
                    {
                        case "codpie_pie":
                            error = this.Validatecodigo();
                            break;
                        case "nombre_pie":
                            error = this.ValidateNombre();
                            break;
                        default:
                            Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                            break;
                    }
                    return error;
                }

                string Validatecodigo()
                {
                    try
                    {
                        if (codpie_pie == null) { return "Debe ingresar el código de la pieza."; }

                        if (codpie_pie != null)
                        {
                            if (codpie_pie.Length > 3) { return "El código de la pieza no puede tener mas de 3 caracteres"; }
                            string error = null;
                            error = validarPieza(codpie_pie);
                            if (!String.IsNullOrEmpty(error))
                            {
                                return error;
                            }
                        }
                        return null;
                    }
                    catch (Exception ex) { MessageBox.Show(ex.Message); }
                    return null;
                }

                string ValidateNombre()
                {
                    try
                    {
                        if (nombre_pie == null) { return "Debe ingresar el nombre de la pieza"; }
                        if (nombre_pie != null)
                        {
                            if (nombre_pie.Length > 50) { return "El nombre de la pieza no puede tener mas de 50 caracteres"; }
                        }
                        return null;
                    }
                    catch (Exception ex) { MessageBox.Show(ex.Message); }
                    return null;
                }

            #endregion
        }
        #endregion
    }
}
